iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
Mobile Development

Android app 效能優化系列 第 11

減少畫面的重複繪製

  • 分享至 

  • xImage
  •  

在我們已經透過 Layout 的優化來減少 UI 的階層,接下來要往繪製的效能來優化。每一次的繪製都需要成本,所以如果可以減少繪製的步驟,就可以提升效率。

重複繪製

當一個 frame 的同一個 pixel 被繪製了多次,就叫重複繪製 (Overdraw)。例如下圖的範例,有一個黃色及藍色的個矩形 View,黃色的部分疊在藍色上面。Android 將會對藍色的View與黃色的 View 各做一次繪製。那麼中間的區塊就是一個重複繪製,因為藍色與黃色的重疊部分繪製了 2 次,多繪製的藍色是使用者看不到的。

https://ithelp.ithome.com.tw/upload/images/20220926/201118962KLJfWqRCG.png

你可能會看到有些中文把 Overdraw 翻譯為過度繪製。其實我們倒不能說這樣就叫過度,這種情況其實就是重複了,同一個 Frame 重複繪製了。既然有重複繪製,就代表其中一個畫面被蓋掉了,使用者也就看不到。對一個看不到的地方進行繪製,當然也就是一種浪費。

減少重複繪製的方式有:

  • 移除不必要的背景
  • 減少 Layout 的複雜度
  • 降低透明度

移除不必要的背景

View 的繪製有 3 個步驟 :Measure、Layout、Draw,而Draw的步驟有:

  1. 繪製 Background
  2. 繪製 View
  3. 繪製 Child
  4. 繪製 Scrollbar

一個常見的錯誤就是把每個 View 都設定了背景色。假設 App 的每個畫面背景顏色都是一樣的,你可以直接在 Themes 使用主題來設定統一的背顏色,就不需要在每個 Activity 裡的 Layout 去設定一樣的背景。即便有時為了好看的排版使用了多層的 Layout 結構,也要注意不要設定了重複的背景色。

在使用元件時,如果元件本身就有會覆蓋在背景上的設定,就不需再設定背景。例如 ImageView 已經在 src 設定了圖片,就不需要在設定 background了。

<ImageView
    android:id="@+id/imageView"
    android:layout_width="60dp"
    android:layout_height="60dp"
	android:src="@mipmap/ic_launcher"
    android:background="@color/teal_200"/>

降低 Layout 的複雜度

Layout 越複雜,效能就可能越差。但多個 ConstraintLayout 或 LinearLayout 儘管都需要依照裡面的所有元件來測量位置,並不會造成太大的效能問題,會造成效能問題的是巢狀的結構。巢狀的結構將使得測量寬高變得複雜並造成重疊的 UI,也就是繪製了很多看不到的東西。減少重疊的 UI 也就能減少重複繪製。只有在你用了複雜的巢狀時會有效能問題。

降低透明度

如果我們將一個 View 設定了透明度,Android 的處理方式會是先繪製原有像素,接著再將其透明化繪製一次。所以如果非必要,就應該減少使用透明度來減少重複繪製。例如要設定一個 Textview 的為 70% 透明的黑色,不應該將文字顏色設定為黑色,再設定 View 的 alpha 為 0.7。而是直接使用透明度 70% 的黑色顏色。

直接從 color 設定透明度70%的黑色
https://ithelp.ithome.com.tw/upload/images/20220926/20111896NzdoB8kKg3.png

<TextView
    android:layout_width="wrap_content"
    android:textColor="#B2000000"
    android:layout_height="wrap_content"/>

設定顏色黑色,alpha 值為 70%,即為顏色#b2000000

了解如何減少重複繪製後,下一篇就來看如何用工具查看是否存在重複繪製。

參考:
https://developer.android.com/topic/performance/rendering/overdraw


上一篇
檢測版面配置 - 使用 Layout Inspector
下一篇
檢測畫面的重複繪製
系列文
Android app 效能優化30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言